/*!
 * Project's name: Ziemianie
 * Supervisor: mgr Tomasz Kornuta, Warsaw University of Technology
 * File's autors: Michal Lisiecki, G1ISI, Warsaw University of Technology
 * Date: 3-12-2008
 * Description:
 * 	SCZR Coursework
 * 	Team: Jakub Rosiak, Michal Lisiecki, Michal Plutecki
 * 	Warsaw University of Technology
 * */

#ifndef CONNECTOR_H_
#define CONNECTOR_H_


#include "Message.h"
#include "MessageListener.h"
#include "Response.h"
#include <list>

/* if sharing a target, change this to something unique for you */
#define SERVER_NAME "KLEWKI_SERVER"

/*!
 * \brief
 * Class used to handle connection details
 * 
 */
class Connector{
	static Connector * connector; //To implement Singleton DP
	
	MessageListener * messageListener;
	
	std::list<pthread_t *> threadList; 
	
	Connector();
	
	/*!
	 * \brief 
	 * Method used to start listening for messages
	 * 
	 * \param name - service name registered in gns
	 * 
	 * \return error code defined in errno
	 */
	int startListening(const char * name);
	
	/*!
	 * \brief
	 * Method used to call deliverMessage
	 * 
	 * \see deliverMessage
	 */
	static void * Run(void * arg);
	
	/*!
	 * \brief
	 * Method delivers message to registered handler
	 * 
	 * \param msg - message to be delivered
	 * 
	 * \return error_code from errno
	 * 
	 * \see Message
	 * \see MessageListener
	 */
	int deliverMessage(Message& msg);
	
	MessageListener * getMessageListener();
	
	/*!
	 * \brief
	 * Method used to sendMessage to server
	 * 
	 * \param serverName - name of server
	 * \param msg - message to be send
	 * 
	 * \return error_code from errno 
	 */
	int sendMessage(const char * serverName, Message * msgm, Response * resp);
	
	/*!
	 * \brief
	 * Method adds thread to list of threads waiting to be joined //TODO discuss
	 * 
	 * \param thread thread to be added
	 * 
	 * \return error_code from errno 
	 */
	void addThread(pthread_t * thread);
	
public:
	virtual ~Connector();
	
	static Connector * GetInstance();
	
	/*! //TODO delete this code
	 * \brief
	 * Method used to get resources
	 * 
	 * \param object - game object type
	 * \param quantity - resource quantity
	 * 
	 * \return error_code from errno
	 */
	//int getResource(int object, int quantity, Response * resp);
	
	/*!
	 * \brief
	 * Method used to get info about resources
	 *
	 * \param object - game object type
	 * \param resp - struct Response containing quantity of resource in relation 
	 * 
	 * \return error_code from errno
	 */
	int getInfo(int object, Response * resp);
	
	/*!
	 * \brief
	 * Method used to get info about relations
	 * 
	 * \param object1 - 1st game object type
	 * \param object2 - 2nd game object type
	 * \param resp -  struct Response containing quantity of resource in relation
	 * 
	 * \return error_code from errno
	 */
	int getInfo(int object1, int object2, Response * resp);
	
	/*!
	 * \brief
	 * Method used to set relation of two objects
	 * 
	 * \param object1 - 1st object type
	 * \param object2 - 2nd object type
	 * \param cardinality - cardinality to be set in given objects  relation
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int setRelation(int object1, int object2, int cardinality, Response * resp);
	
	/*!
	 * \brief
	 * Method used to drop relation of two objects
	 * 
	 * \param object1 - 1st game object type
	 * \param object2 - 1st game object type
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int dropRelation(int object1, int object2, Response * resp);
	
	/*!
	 * \brief
	 * Method used to add some objects
	 * 
	 * \param object - game object type
	 * \param quantity - quantity to add
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int add(int object, int quantity, Response * resp);
	
	/*!
	 * \brief
	 * Method used to add some resources to relation
	 * 
	 * \param object1 - 1st game object type
	 * \param object2 - 2nd game object type
	 * \param quantity - quantity of objects in relation to add
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int add(int object1, int object2, int quantity, Response * resp);
	
	/*!
	 * \brief
	 * Method used to take some objects from DB
	 * 
	 * \param object - game object type
	 * \param quantity - quantity of object to take
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int take(int object, int quantity, Response * resp);
	
	/*!
	 * \brief
	 * Method used to take some resources from relation
	 * 
	 * \param object1 - 1st game object type
	 * \param object2 - 2nd game object type
	 * \param quantity - quantity of objects relation to take
	 * \param resp - struct Response containing status of the operation
	 * 
	 * \return error_code from errno
	 */
	int take(int object1, int object2, int quantity, Response * resp);
	
	/*!
	 * \brief
	 * Method used to request building of objects
	 * 
	 * \param objectType - type of object to build
	 * \return error_code from errno
	 */
	int build(int object);
	
	/*!
	 * \brief
	 * method called to ping server in order to confirm availibility
	 * \return error_code from errno
	 */
	int ping();
	
	/*!
	 * \brief
	 * Method that starts Server service
	 */
	void runServer();
	
	/*!
	 * \brief
	 * Method that starts client service
	 * 
	 * \param clientName - name of service to be registered in qns
	 */
	void runClient(const char * clientName);
	
	/*!
	 * \brief
	 * MessageListener setter
	 */
	void setMessageListener(MessageListener * messageListener);
	
	//TODO: add method destroy(object) - used to request destroying of object
	
	
};

#endif /*CONNECTOR_H_*/
